package lee.vioson.ebook.ui.components

import android.util.Log
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import kotlin.math.roundToInt

@Composable
fun NextScrollableBox(
    modifier: Modifier = Modifier,
    headerHeight: Dp = 500.dp,
    header: @Composable BoxScope.() -> Unit,
    listItem: LazyListScope.() -> Unit
) {
    // ToolBar 最大向上位移量
    val density = LocalDensity.current
    val maxUpPx = with(density) { headerHeight.roundToPx().toFloat() }
    // ToolBar 最小向上位移量
    val minUpPx = 0f
    // 偏移折叠工具栏上移高度
    var headerOffsetHeightPx by rememberSaveable { mutableStateOf(0f) }

    var listTopPaddingPx by rememberSaveable { mutableStateOf(with(density) { headerHeight.toPx() }) }

    val lazyColumnState = rememberLazyListState()
    val nestedScrollConnection = remember {
        object : NestedScrollConnection {
            override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
                val delta = available.y
                if (delta > 0 &&
                    lazyColumnState.firstVisibleItemIndex > 0 ||
                    (lazyColumnState.firstVisibleItemIndex == 0 && lazyColumnState.firstVisibleItemScrollOffset != 0)
                ) {
                    return Offset.Zero
                }
                val newOffset = headerOffsetHeightPx + delta
                // 设置 ToolBar 的位移范围
                headerOffsetHeightPx = newOffset.coerceIn(-maxUpPx, -minUpPx)

                val toolBarHeightPx = with(density) { headerHeight.toPx() }
                listTopPaddingPx =
                    (toolBarHeightPx + headerOffsetHeightPx).coerceIn(0f, toolBarHeightPx)
                Log.d(
                    "BookDetail",
                    "delta=$delta,toolbarOffsetHeightPx=$headerOffsetHeightPx,listTopPaddingPx=$listTopPaddingPx"
                )
                return if (listTopPaddingPx == 0f || listTopPaddingPx == toolBarHeightPx)
                    Offset.Zero else available
            }
        }
    }
    Box(
        modifier = Modifier
            .then(modifier)
            .fillMaxSize()
            .nestedScroll(nestedScrollConnection)
    ) {
        LazyColumn(
            state = lazyColumnState,
            contentPadding = PaddingValues(top = with(density) { listTopPaddingPx.toDp() }),
            content = listItem
        )
        ScrollableAppBar(
            scrollableAppBarHeight = headerHeight,
            toolbarOffsetHeightPx = headerOffsetHeightPx,
            content = header
        )
    }
}

@Composable
fun ScrollableAppBar(
    modifier: Modifier = Modifier,
    scrollableAppBarHeight: Dp,
    toolbarOffsetHeightPx: Float, //向上偏移量
    content: @Composable BoxScope.() -> Unit,
) {
    Box(modifier = Modifier
        .then(modifier)
        .height(scrollableAppBarHeight)
        .offset {
            IntOffset(x = 0, y = toolbarOffsetHeightPx.roundToInt()) //设置偏移量
        }
        .fillMaxWidth()
    ) {
        content()
    }
}